home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 8
/
FM Towns Free Software Collection 8.iso
/
t_os
/
pao
/
etc
/
cdir
/
src
/
sdump.c
< prev
next >
Wrap
Text File
|
1994-06-01
|
14KB
|
455 lines
/* << MSC V5.1 >> [FM-TOWNS] ************************************************
*
* カレントドライブのセクタダンププログラム(MS-DOS汎用)
* ----------------------------------------------------------------------
* All Rights Reserved, Copyright (C) Y.Hirata 1993.
* Programmed by Y.Hirata ( NIFTY-ID: NAB03321 パオパオ )
*
* NOTE: TAB=4
****************************************************************************/
#include <stdio.h> /* printf,putchar */
#include <stdlib.h> /* exit */
#include <string.h> /* str* */
#include <jctype.h> /* iskanji* */
#include <direct.h> /* getcwd */
#include <conio.h> /* getch */
#include "lib\define.h" /* 定数宣言 */
#include "lib\typedef.h" /* 型宣言 */
#include "lib\mem.h" /* _peek */
#include "lib\dirlib.h" /* <dos.h>,_aread */
#include "lib\doscall.h" /* <dos.h>,_getDPB */
#include "lib\crt.h" /* ANK,・・・ */
#define isdisp(c) ((0x20 <= c && c < 0x7F) || (0xA0 <= c && c <= 0xDF))
_DPB _dpb ; /* DPB情報 */
int FATbit ; /* FATビットサイズ */
unsigned _cdrv ; /* カレントドライブ */
char *_cdir ; /* カレントディレクトリ */
char _abspath[128] ; /* 物理パス名 */
BYTE *_sctbuf ; /* セクタ領域 */
DWORD _fsector ; /* 開始セクタ番号 */
DWORD _nsector ; /* 読み取りセクタ数 */
#define LINEpPAGE 24 /* 1画面の行数 */
int _linecnt ; /* 表示行数 */
struct {
unsigned critical:1 ; /* 致命的エラー発生フラグ */
unsigned fat:1 ; /* FAT読み込み済フラグ */
unsigned sct32:1 ; /* 32bitサポートフラグ */
unsigned page:1 ; /* ページ制御 */
} _flg ; /* 処理フラグ */
void putcrlf( void )
/*===========================================================================
* 改行表示
===========================================================================*/
{
putchar( '\n' ) ;
if ( !_flg.page ) return ;
if ( ++_linecnt > LINEpPAGE-2 ) {
printf( "--- more ---" ) ;
getch() ;
putchar( '\n' ) ;
_linecnt=0 ;
}
}
void getDPB( void )
/*===========================================================================
* DPB情報取得
===========================================================================*/
{
WORD attr ;
_getDPB( _cdrv,&_dpb ) ;
if ( _dpb.maxclst < 0x0FF7 ) {
FATbit = 12 ; /* 12bit FAT */
} else {
FATbit = 16 ; /* 16bit FAT */
}
if ( _osmajor >= 10 ) { /* OS/2互換BOX */
_flg.sct32 = 1 ;
return ;
}
attr = (WORD)_peek( _dpb.dseg,_dpb.doff+4 ) ;
_flg.sct32 = ( attr & 0x0002 ) ? 1 : 0 ; /* 32bitセクタサポート? */
}
int absRead( WORD nsct,DWORD sctno,void *buf )
/*===========================================================================
* 物理読み込み
* < IN > : nsct 読み込みセクタ数
* : sctno 読み込み開始セクタ番号
* : buf データ格納先アドレス
* < OUT > : buf 読み込んだデータ
* < RET > : 下位バイトにエラーコードを返す. (上位バイト=00h:正常終了, =01h:エラー発生)
* =00h 書き込み禁止である
* =01h ユニットが存在しない
* =02h ドライブの準備ができていない
* =03h 存在しないコマンドである
* =04h データのCRCエラー
* =05h バッドドライブリクエストストラクチャの長さ
* =06h シークエラー
* =07h 存在しないメディアタイプである
* =08h セクタが存在しない
* =09h プリンタの用紙切れ
* =0Ah 書き込み不良
* =0Bh 読み込み不良
* =0Ch 一般的なディスク不良
* =0Fh 不正なメディア交換があった
===========================================================================*/
{
struct {
DWORD sctno ; /* 32bitセクタ番号 */
WORD nsct ; /* R/Wセクタ数 */
WORD off ; /* バッファオフセット */
WORD seg ; /* バッファセグメント */
} packet ;
if ( _flg.sct32 ) { /* 32bitセクタサポート */
packet.sctno = sctno ;
packet.nsct = nsct ;
packet.off = _off( buf ) ;
packet.seg = _seg( buf ) ;
return _aread( _cdrv-1,-1,-1,&packet ) ;
}
return _aread( _cdrv-1,nsct,(WORD)sctno,buf ) ;
}
void dispTitle( DWORD fsector )
/*===========================================================================
* セクタダンプのタイトル表示
* < IN > : fsector 開始セクタ番号
===========================================================================*/
{
putcrlf() ;
printf( "< セクタ番号 %lXh >",fsector ) ;
putcrlf() ;
printf( "---- + -- -- -- -- -- -- -- -- . " ) ;
printf( "-- -- -- -- -- -- -- -- + -------- -------- " ) ;
putcrlf() ;
}
int dispKanji( int kanji1,int kanji2 )
/*===========================================================================
* 漢字表示(漢字1バイト目確定, 2バイト目非確定時の処理)
* < IN > : kanji1 漢字1バイト目
* : kanji2 漢字2バイト目
* < RET > : 漢字表示有無
* =0 漢字表示(2バイト表示)
* =1 非漢字表示(1バイト表示)
===========================================================================*/
{
if ( iskanji2( kanji2 ) ) { /* 漢字表示 */
putchar( kanji1 ) ;
putchar( kanji2 ) ;
return 0 ;
} else { /* 制御文字表示 */
putchar( '.' ) ;
return 1 ;
}
}
void dispAscii( WORD off,int *prech,int *kanji )
/*===========================================================================
* ASCII/S-JIS表示
* < IN > : off オフセット
* : prech ひとつ前の値
* : kanji 漢字チェックフラグ
* < OUT > : prech 最後の値(漢字1バイト目)
* : kanji 漢字チェックフラグ
===========================================================================*/
{
register WORD cnt ;
if ( *kanji != ANK ) { /* 先頭が漢字2バイト目 */
putchar( ' ' ) ;
*kanji = ANK ;
} else {
*kanji = iskanji( _sctbuf[off] ) ? KANJI1 : ANK ;
if ( *kanji == ANK ) { /* 漢字1バイト目以外 */
if ( isdisp( _sctbuf[off] ) ) /* 表示可能文字 */
putchar( _sctbuf[off] ) ;
else /* 制御文字等 */
putchar( '.' ) ;
} else /* 漢字1バイト目=保留 */
*prech = _sctbuf[off] ;
}
off++ ;
for ( cnt=1; cnt<16; cnt++, off++ ) { /* 2文字目以降表示 */
if ( cnt == 8 && *kanji == ANK ) putchar( ' ' ) ;
if ( off < _dpb.bps ) { /* データ読取範囲内 */
if ( *kanji != ANK ) { /* 漢字2バイト目? */
if ( dispKanji( *prech,_sctbuf[off] ) ) {
*kanji = iskanji( _sctbuf[off] ) ? KANJI1 : ANK ;
} else /* 漢字表示済 */
*kanji = KANJI2 ;
if ( cnt == 8 ) putchar( ' ' ) ;
} else { /* 漢字1バイト目/ANK */
*kanji = iskanji( _sctbuf[off] ) ? KANJI1 : ANK ;
}
if ( *kanji == ANK ) { /* ANK(漢字以外) */
if ( isdisp( _sctbuf[off] ) )
putchar( _sctbuf[off] ) ;
else
putchar( '.' ) ;
} else /* 漢字1バイト目=保留 */
*prech = _sctbuf[off] ;
if ( *kanji == KANJI2 ) *kanji = ANK ;
} else /* データ読取範囲外 */
putchar( '.' ) ;
}
}
int dispSector( DWORD sector )
/*===========================================================================
* セクタ内容表示
* < IN > : sector セクタ番号
* < RET > : 最後の表示有無
* =0 ANK(表示済)
* =1 未表示(最後の1バイト表示待ち)
===========================================================================*/
{
register WORD cnt, off=0 ;
static int prech=0, kanji=ANK ;
if ( kanji != ANK ) { /* 前回未表示分あり */
if ( dispKanji( prech,_sctbuf[0] ) ) kanji = ANK ;
}
dispTitle( sector ) ; /* タイトル表示 */
for ( off=0; off<_dpb.bps; off+=16 ) {
if ( off ) {
if ( kanji != ANK ) { /* 前行未表示分あり */
if ( dispKanji( prech,_sctbuf[off] ) ) kanji = ANK ;
}
putcrlf() ; /* 改行 */
}
printf( "%04X |",off ) ; /* オフセット表示 */
for ( cnt=0; cnt<16; cnt++, off++ ) { /* dump */
if ( cnt == 8 ) printf( " -" ) ;
if ( off < _dpb.bps ) /* データ読取範囲内 */
printf( " %02X",_sctbuf[off] ) ;
else /* データ読取範囲外 */
printf( " .." ) ;
}
off -= 16 ;
printf( " | " ) ;
dispAscii( off,&prech,&kanji ) ; /* ASCII/S-JIS表示 */
}
return kanji==ANK ? 0 : 1 ;
}
int dump( void )
/*===========================================================================
* セクタダンプ
* < RET > : エラコードを返す.
* =0 正常終了
* =1 セクタ読み込み失敗
===========================================================================*/
{
DWORD cnt ;
int ret ;
for ( cnt=0L; cnt<_nsector; cnt++ ) {
ret = absRead( 1,_fsector+cnt,_sctbuf ) ;
if ( ret ) {
printf( "\aセクタ読み込み失敗 _aread error : %02Xh",_lo(ret) ) ;
printf( ", セクタ番号 %lXh",_fsector+cnt ) ;
putcrlf() ;
return 1 ;
}
ret = dispSector( _fsector+cnt ) ; /* セクタ内容表示 */
}
if ( ret ) putchar( '.' ) ;
putcrlf() ;
return 0 ;
}
int abschk( void )
/*===========================================================================
* 物理アクセスのチェック
===========================================================================*/
{
if ( getabspath( _cdir,_abspath ) ) { /* 物理パス名取得 */
_flg.critical = 1 ;
printf( "\a ドライブの指定が違います." ) ;
putcrlf() ;
return 1 ;
}
if ( isnetdrv( _cdrv ) ) { /* リモート */
putcrlf() ;
printf( "\a %c: はリモートドライブ",_cdrv+'@' ) ;
printf( "(DOSによる物理アクセス不可)のため扱えません." ) ;
putcrlf() ;
return 1 ;
}
if ( isjoindrv( _cdrv ) || stricmp( _cdir,_abspath ) ) {
putcrlf() ;
printf( "\a このドライブは再割当されています." ) ;
putcrlf() ;
printf( " 物理パス名は %s",_abspath ) ;
putcrlf() ;
}
return 0 ;
}
int init( void )
/*===========================================================================
* 初期処理
* < RET > : エラコードを返す.
* =0 正常終了
* =1 メモリ不足
* =2 物理アクセス不可
===========================================================================*/
{
_flg.critical = 0 ;
resetdisk() ; /* リセットディスク */
_dos_getdrive( &_cdrv ) ; /* カレントドライブ */
_cdir = getcwd( NULL,_MAX_DIR ) ; /* カレントディレクトリ取得 */
if ( abschk() ) return 2 ; /* 物理アクセスチェック */
getDPB() ; /* DPB情報取得 */
if ( (_sctbuf = (BYTE *)malloc( _dpb.bps )) == NULL ) {
printf( "\a作業領域(%dbyte)が確保できませんでした.",_dpb.bps ) ;
putcrlf() ;
return 1 ;
}
return 0 ;
}
void dispDpb( void )
/*===========================================================================
* ディスク情報表示
===========================================================================*/
{
putcrlf() ;
printf( "< %d bit FAT >",FATbit ) ;
if ( _flg.sct32 ) printf( " ( 32bitセクタ番号サポート )" ) ;
putcrlf() ;
printf( "bytes/sector .................. %u",_dpb.bps ) ;
putcrlf() ;
printf( "sectors/cluster ............... %u",_dpb.spc+1 ) ;
putcrlf() ;
printf( "reserved sectors .............. %u",_dpb.res ) ;
putcrlf() ;
printf( "sectors/FAT ................... %u",_dpb.spf ) ;
putcrlf() ;
printf( "first data sector ............. %04Xh",_dpb.fds ) ;
putcrlf() ;
printf( "first sector of root directry . %04Xh",_dpb.fsr ) ;
putcrlf() ;
}
void usage( void )
/*===========================================================================
* 使用方法表示
===========================================================================*/
{
printf( "セクタダンプ (C) パオパオ 1993.\n\n" ) ;
printf( "Usage: sdump 開始セクタ番号 [セクタ数] [-p]\n" ) ;
printf( " -p 1画面毎表示\n" ) ;
printf( "( 16進数値は, ********H です. )\n" ) ;
exit( 1 ) ;
}
void swchk( char *str )
/*===========================================================================
* オプションスイッチ評価
===========================================================================*/
{
register int cnt ;
for ( cnt=0; cnt<strlen(str); cnt++ ) {
if ( str[cnt] == '-' || str[cnt] == '/' ) continue ;
switch ( str[cnt] ) {
case 'p' :
case 'P' :
_flg.page = TRUE ; break ;
default :
usage() ;
}
}
}
int atoc( BYTE ch,int radix )
/*===========================================================================
* 文字→数字
===========================================================================*/
{
if ( ch >= '0' && ch <= '9' ) return ( ch - '0' ) ;
if ( radix == 16 ) {
if ( ch >= 'a' && ch <= 'f' ) return ( ch - 'a' + 10 ) ;
if ( ch >= 'A' && ch <= 'F' ) return ( ch - 'A' + 10 ) ;
}
printf( "\a数値の指定に誤りがあります.\n" ) ;
exit( 1 ) ;
}
DWORD atohl( char *str )
/*===========================================================================
* 文字列→数字(double word)
===========================================================================*/
{
register int cnt ;
int len=strlen( str ) ;
BYTE ch ;
DWORD val=0L ;
ch = str[len-1] ;
if ( ch == 'h' || ch == 'H' ) { /* 16進数 */
for ( cnt=0; cnt<len-1; cnt++ ) {
val <<= 4 ;
val += (DWORD)atoc( str[cnt],16 ) ;
}
} else { /* 10進数 */
for ( cnt=0; cnt<len; cnt++ ) {
val *= 10L ;
val += (DWORD)atoc( str[cnt],10 ) ;
}
}
return val ;
}
int main( int ac,char *av[] )
/*===========================================================================
* メイン
===========================================================================*/
{
int ret, cnt ;
if ( ac < 2 ) usage() ; /* 使用方法表示 */
_flg.page = 0 ;
_linecnt = 0 ;
_nsector = 1L ;
for ( ret=0, cnt=1; cnt<ac; cnt++ ) {
if ( *av[cnt] == '-' || *av[cnt] == '/' )
swchk( av[cnt]+1 ) ; /* 引数チェック */
else {
switch ( ret ) {
case 0 :
_fsector = atohl( av[cnt] ) ; /* 開始セクタ番号 */
ret++ ;
break ;
case 1 :
_nsector = atohl( av[cnt] ) ; /* 読み取りセクタ数 */
ret++ ;
break ;
default :
usage() ; /* 使用方法表示 */
}
}
}
ret = init() ; /* 初期処理 */
if ( ret != 2 ) dispDpb() ; /* ディスク情報表示 */
if ( !ret ) dump() ; /* セクタダンプ */
if ( _sctbuf != NULL ) free( _sctbuf ) ; /* データクリア */
resetdisk() ; /* リセットディスク */
return 0 ;
}